/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Data;

import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import javax.swing.table.DefaultTableModel;
import org.apache.log4j.Logger;
import Gramatica.*;
import java.io.FileInputStream;
import org.apache.log4j.PropertyConfigurator;
/**
 *
 * @author REI
 */
public class Variables {
    
    ArrayList<Sim> tabla;
    ListaError lista;
    ArrayList<String> listaimports;
    private final static Logger log = Logger.getLogger(Variables.class);
    int mem;
    int pil;
    public String nombreclase;

    public Variables(ListaError lista, ArrayList<String> listaimports) {
        this.tabla = new ArrayList<Sim>();
        this.lista = lista;
        this.listaimports = listaimports;
        this.mem =0;
        this.pil =0;
    }

    public ArrayList<Sim> getTabla() {
        return tabla;
    }

    public void setTabla(ArrayList<Sim> tabla) {
        this.tabla = tabla;
    }

    
    public ListaError getLista() {
        return lista;
    }

    public void setLista(ListaError lista) {
        this.lista = lista;
    }

    public ArrayList<String> getListaimports() {
        return listaimports;
    }

    public void setListaimports(ArrayList<String> listaimports) {
        this.listaimports = listaimports;
    }

    public int getMem() {
        return mem;
    }

    public void setMem(int mem) {
        this.mem = mem;
    }

    public int getPil() {
        return pil;
    }

    public void setPil(int pil) {
        this.pil = pil;
    }

    public String getNombreclase() {
        return nombreclase;
    }

    public void setNombreclase(String nombreclase) {
        this.nombreclase = nombreclase;
    }

    
    
    public void ErrorSemantico(Token tok, String msg)
    {
        
            lista.AgregarError(tok.getLinea(),tok.getColumna(),tok.getLexema() ,"Error Semantico en Clase "+nombreclase,msg);
	    log.info("Linea: "+tok.getLinea()+" Columna: "+tok.getColumna()+" Simbolo: "+tok.getLexema()+" Error Semantico en Clase "+nombreclase+" "+msg);
            System.out.println(msg);
        
        
    }

    public DefaultTableModel getDtm()
    {

        String [] titulos= {"Nombre","Tipo","Ambito","Rol","Visibilidad","Dimensiones","Tamaño","Num. Parametros","Tipo Parametros",
                            "Posicion Pila","Posicion","Name"};
        DefaultTableModel dtm = new DefaultTableModel(null,titulos);




        for(Sim simbolo: tabla)
        {
            Object data[] = {simbolo.getNombre(),simbolo.getTipo(),simbolo.getAmbito(),simbolo.getRol(),
                             simbolo.getVisibilidad(),simbolo.getDimensiones(),simbolo.getSize(),simbolo.getNumparams(),
                             simbolo.getParams(),simbolo.getPospila(),simbolo.getPos(),simbolo.getName()};

            dtm.addRow(data);
        }



        return dtm;
    }
    
    public String nuevoAmbito(String ambito[], int num)
    {
        String ambi= "";
        for(int i=0; i <= num; i++)
        {
            if(i==0)
            {
                ambi = ambi + ambito[i];
            }
            else
            {
                ambi = ambi +"/"+ambito[i];
            }
        }
        return ambi;    
    }
    
    public Sim agregarClase(int visibilidad,Object clas )
    {
        Sim simbolo;
        simbolo  = new Sim();
        Token clase[] = (Token[])clas;
        simbolo.setVisibilidad(visibilidad);
        simbolo.setRol(Tipo.CLASE);
        
        if(clase.length>1)
        {
            String nom = (clase[0]).getLexema();
            String hereda = (clase[1]).getLexema();
            simbolo.setNombre(nom);
            nombreclase = nom;
            simbolo.setHeredade(hereda);
            agregarClaseTabla(clase[0], nom, simbolo);
        }
        else
        {
            String nom = ((Token)clase[0]).getLexema();
            nombreclase = nom;
            simbolo.setNombre(nom);
            agregarClaseTabla(clase[0], nom, simbolo);
        }
        
        return simbolo;
    }
    
    public void agregarClaseTabla(Token token, String nom, Sim clase)
    {
        String rol;
        String name;
        boolean encontrado;
        encontrado = false;
        for(Sim simbolo : tabla)
        {
            rol = simbolo.getRol();
            
            if(rol.compareTo(Tipo.CLASE)==0)
            {
                name = simbolo.getNombre();
                if(nom.compareTo(name)==0)
                {
                    encontrado = true;
                    break;
                }
            }
        }
        
        if(!encontrado)
        {
            tabla.add(clase);
        }
        else
        {
            ErrorSemantico(token, "La clase que desea agregar ya fue declarada");
        }
    }
    
    public void agregarVariable(int visibilidad, int tipo, String ambitoactual, int size, Object vars, Object val, boolean global)
    {
        ArrayList<Token> variables = (ArrayList<Token>)vars;
        Sim simbolo;
        String nom;
        String name;
        
        
        
        
        

        for(Token var: variables)
        {
            nom = var.getLexema();
            simbolo = new Sim();
            simbolo.setVisibilidad(visibilidad);
            simbolo.setTipo(tipo);
            simbolo.setNombre(nom);
            simbolo.setAmbito(ambitoactual);
            simbolo.setRol(Tipo.VARIABLE);
            simbolo.setSize(size);
            simbolo.setValor(val);
            name = ambitoactual+"#"+nom;
            simbolo.setName(name);
            if(global)
            {
                simbolo.setPos(mem);
                simbolo.setPospila(-1);
                mem = mem + size;
            }
            else
            {
                simbolo.setPospila(pil);
                simbolo.setPos(-1);
                pil = pil + size;
            }

            agregarVariableTabla(simbolo, var);


      }
        
        
        
    }
    
    public void agregarVariableTabla(Sim simbolo, Token var)
    {
        
        String name;
        String rol;
        String nomvar;
        boolean encontrado = false;
        String ambitos[] = simbolo.getAmbito().split("/");
        int numabitos = ambitos.length;
        String ambitoactual;
        
        for(int i = numabitos - 1; i>=0; i-- )
        {
            ambitoactual = nuevoAmbito(ambitos, i);
            name = ambitoactual+"#"+simbolo.getNombre();
            
            for(Sim variable: tabla)
            {
                rol = variable.getRol();
                if(rol.compareTo(Tipo.VARIABLE)==0 || rol.compareTo(Tipo.OBJETO)==0)
                {
                    nomvar = variable.getName();
                    if(name.compareTo(nomvar)==0)
                    {
                        encontrado = true;
                        break;
                    }

                }

            }
            
        }
        
        
        if(!encontrado)
        {
            tabla.add(simbolo);
        }
        else
        {
            ErrorSemantico(var,"La variable ya ha sido declarada");
        }
    }
    
    public Sim agregarParametro(Object param, String ambitoactual, int pos)
    {
        Sim simbolo = new Sim();
        Object valores[] = (Object[])param;
        int tipo = (Integer)valores[0];
        Token token = (Token)valores[1];
        String nom = token.getLexema();
        int ref = (Integer)valores[2];
        int size = (Integer)valores[3];
        Token instan;
        String name;
        
        simbolo.setTipo(tipo);
        simbolo.setNombre(nom);
        simbolo.setRol(Tipo.PARAMETRO);
        simbolo.setAmbito(ambitoactual);
        simbolo.setPospila(pil);
        simbolo.setPos(-1);
        pil = pil+ size;
        simbolo.setReferencia(ref);
        name = ambitoactual+"#"+nom;
        simbolo.setName(name);
        if(valores.length>4)
        {
            instan = (Token)valores[4];
        }
        else
        {
            simbolo.setSize(size);
        }
        
        agregarParametroTabla(simbolo, token);
        return simbolo;
    }
    
    public void agregarParametroTabla(Sim simbolo, Token var)
    {
        String name = simbolo.getName();
        String rol;
        String nomvar;
        boolean encontrado = false;
        for(Sim variable: tabla)
        {
            rol = variable.getRol();
            
            if(rol.compareTo(Tipo.PARAMETRO)==0)
            {
                nomvar = variable.getName();
                
                if(nomvar.compareTo(name)==0)
                {
                    encontrado = true;
                    break;
                }
            }
        }
        
        if(!encontrado)
        {
            tabla.add(simbolo);
        }
        else
        {
            ErrorSemantico(var,"El parametro ya ha sido declarado");
        }
    }
    
    public void modificarAmbitoParametros(Object params, String ambitoactual)
    {
        ArrayList<Sim> parametros = (ArrayList<Sim>)params;
        String name;
        for(Sim simbolo: parametros)
        {
            name = ambitoactual+"#"+simbolo.getNombre();
            simbolo.setName(name);
            simbolo.setAmbito(ambitoactual);
        }
    }

    public void agregarAmbito(int size, String nombre)
    {

        boolean encontrado = false;
        String rol;
        String nom;
        for(Sim simbolo: tabla)
        {
            rol = simbolo.getRol();

            if(rol.compareTo(Tipo.AMBITO)==0)
            {
                nom = simbolo.getNombre();
                if(nom.compareTo(nombre)==0)
                {
                    encontrado = true;
                    break;
                }
            }
        }

        if(!encontrado)
        {
            Sim simbolo = new Sim();
            simbolo.setNombre(nombre);
            simbolo.setSize(pil);
            simbolo.setRol(Tipo.AMBITO);
            tabla.add(simbolo);
        }

    }

    public void agregarArreglo(int visibilidad, int tipo, String ambitoactual, Object vars, Object val, Object dimensiones, boolean global)
    {
        Token var = (Token)vars;
        Sim simbolo;
        String nom;
        String name;
        ArrayList<String> dimens = (ArrayList<String>)dimensiones;
        int fin = dimens.size();
        String valdim;
        int tam =1;
        for(int i=0; i < fin; i++)
        {
            valdim = dimens.get(i);
            if(valdim.compareTo("-1")==0)
            {
                ErrorSemantico(var,"El valor de la dimension No: "+(i+1)+" no es valido");
            }
            else
            {
                tam = tam * Integer.parseInt(valdim);
            }
        }

        nom = var.getLexema();
        simbolo = new Sim();
        simbolo.setVisibilidad(visibilidad);
        simbolo.setTipo(tipo);
        simbolo.setNombre(nom);
        simbolo.setAmbito(ambitoactual);
        simbolo.setRol(Tipo.ARREGLO);
        simbolo.setSize(tam);
        simbolo.setDimensiones(fin);
        simbolo.setTam_dimensiones(dimens);
        simbolo.setValor(val);
        name = ambitoactual+"#"+nom;
        simbolo.setName(name);
        if(global)
        {
            simbolo.setPos(mem);
            mem = mem + tam;
        }
        else
        {
            simbolo.setPospila(pil);
            pil = pil + tam;
        }

        agregarArregloTabla(simbolo, var);





       
    }

    public void agregarArregloTabla(Sim simbolo, Token var)
    {

        String name;
        String rol;
        String nomvar;
        boolean encontrado = false;
        String ambitos[] = simbolo.getAmbito().split("/");
        int numabitos = ambitos.length;
        String ambitoactual;

        for(int i = numabitos - 1; i>=0; i-- )
        {
            ambitoactual = nuevoAmbito(ambitos, i);
            name = ambitoactual+"#"+simbolo.getNombre();

            for(Sim variable: tabla)
            {
                rol = variable.getRol();
                if(rol.compareTo(Tipo.ARREGLO)==0)
                {
                    nomvar = variable.getName();
                    if(name.compareTo(nomvar)==0)
                    {
                        encontrado = true;
                        break;
                    }

                }

            }

        }


        if(!encontrado)
        {
            tabla.add(simbolo);
        }
        else
        {
            ErrorSemantico(var,"El arreglo ya ha sido declarado");
        }
    }

    public Sim agregarFuncion(int visibilidad, int tipo, Object var, String ambitoactual, int tam, int num_par, String params, ArrayList<String> listref)
    {
        
        Token variable = (Token)var;
        String nombre = variable.getLexema();
        Sim simbolo = new Sim();
        simbolo.setVisibilidad(visibilidad);
        simbolo.setTipo(tipo);
        simbolo.setRol(Tipo.FUNCION);
        simbolo.setAmbito(ambitoactual);
        simbolo.setNombre(nombre);
        simbolo.setSize(pil);
        simbolo.setNumparams(num_par);
        simbolo.setParams(params);
        simbolo.setTam_dimensiones(listref);
        String name = ambitoactual+"#"+nombre+params;
        simbolo.setName(name);
        if(Tipo.VOID != tipo)
        {
            simbolo.setPos(mem);
            simbolo.setPospila(-1);
            mem = mem +  tam;
        }
        else
        {
            simbolo.setPos(0);
        }

        agregarFuncionTabla(simbolo, variable);

        return simbolo;

    }

    public void agregarFuncionTabla(Sim simbolo, Token var)
    {

        String name;
        String rol;
        String nomvar;
        boolean encontrado = false;
        String ambitos[] = simbolo.getAmbito().split("/");
        int numabitos = ambitos.length;
        String ambitoactual;

        for(int i = numabitos - 1; i>=0; i-- )
        {
            ambitoactual = nuevoAmbito(ambitos, i);
            name = ambitoactual+"#"+simbolo.getNombre()+simbolo.getParams();

            for(Sim variable: tabla)
            {
                rol = variable.getRol();
                if(rol.compareTo(Tipo.FUNCION)==0)
                {
                    nomvar = variable.getName();
                    if(name.compareTo(nomvar)==0)
                    {
                        encontrado = true;
                        break;
                    }

                }

            }

        }


        if(!encontrado)
        {
            tabla.add(simbolo);
        }
        else
        {
            ErrorSemantico(var,"La funcion ya ha sido declarada");
        }
    }


    public Sim buscarVariable(Token var, String ambito)
    {
        String name;
        String rol;
        String nomvar;
        boolean encontrado = false;
        String ambitos[] = ambito.split("/");
        int numabitos = ambitos.length;
        String ambitoactual;
        Sim buscada= null;

        for(int i = numabitos - 1; i>=0; i-- )
        {
            ambitoactual = nuevoAmbito(ambitos, i);
            name = ambitoactual+"#"+var.getLexema();

            for(Sim variable: tabla)
            {
                rol = variable.getRol();
                if(rol.compareTo(Tipo.FUNCION)!=0 && rol.compareTo(Tipo.AMBITO)!=0 && rol.compareTo(Tipo.CLASE)!=0)
                {
                    nomvar = variable.getName();
                    if(name.compareTo(nomvar)==0)
                    {
                        encontrado = true;
                        buscada = variable;
                        
                        if(variable.getRol().compareTo(Tipo.PARAMETRO)==0)
                        {
                            return buscada;
                        }
                        
                    }

                }

            }

        }


        if(encontrado)
        {
            return buscada;
        }
        else
        {
            ErrorSemantico(var,"La variable no existe");
            return null;
        }

    }

    public NodoValor getTipoVariable(Token var, String ambito)
    {
        NodoValor valor;
        Sim simbolo;

        simbolo = buscarVariable(var, ambito);

        if(simbolo!=null)
        {
            valor = new NodoValor(var.getLexema(),simbolo.getTipo());
            return valor;
        }
        else
        {
            valor = new NodoValor(null,-1);
            return valor;
        }

    }
    
    public int getTipoVar(Token var, String ambito)
    {
        int valor;
        Sim simbolo;

        simbolo = buscarVariable(var, ambito);

        if(simbolo!=null)
        {
            valor = simbolo.getTipo();
            return valor;
        }
        else
        {
            valor = -1;
            return valor;
        }

    }


    public void agregarImports(ArrayList<Token> lista, String direccion)
    {
        String nombre;
        ArrayList<Sim> tablas;
        for(Token importe: lista)
        {
            nombre = importe.getLexema();
            tablas = obtenerTablaImpor(importe, direccion, nombre+".java");
            if(tablas!=null)
            {
                tabla.addAll(tablas);
            }
        }
    }
    

    public ArrayList<Sim> obtenerTablaImpor(Token importe, String direccion, String nombre)
    {
        ArrayList tablasim = null;
        parser primera;
        parserv segunda;
        File file = new File(direccion+nombre);
        PropertyConfigurator.configure("log4j.properties");
        try {
            primera = new parser(new lex(new FileInputStream(file)));
            primera.setNombre(nombre);
            primera.setDireccion(direccion);
            primera.parse();
            segunda = new parserv(new lexv(new FileInputStream(file)));
            segunda.list = primera.list;
            segunda.var = primera.var;
            segunda.parse();

            if(segunda.list.estaVacia())
            {
                tablasim = segunda.var.getTabla();
            }
            else
            {
                ErrorSemantico(importe, "Existen errores en el archivo importado");
            }

        } catch (Exception ex) {
            java.util.logging.Logger.getLogger(Variables.class.getName()).log(Level.SEVERE, null, ex);
        }


        return tablasim;
    }
    
    public NodoValor verficarLLamadas(Token objeto, Token funcion, int numpar, String params, String ambitoactual)
    {
        String nombreobj;
        String nombrefun;
        NodoValor val =null;
        if(objeto!=null) // instancia
        {
            
            Sim instancia = buscarVariable(objeto, ambitoactual);
            if(instancia!=null)
            {
                if(instancia.getRol().compareTo(Tipo.OBJETO)==0)
                {
                    nombreobj = instancia.getInstancia();
                    Sim buscada = buscarFuncion(funcion, nombreobj, numpar, params);
                    if(buscada==null)
                    {
                        ErrorSemantico(funcion, "La funcion no existe");
                        val = new NodoValor(null,-1);
                    }
                    else
                    {
                        if(buscada.getVisibilidad()==Tipo.PRIVATE || buscada.getVisibilidad()==Tipo.PROTECTED)
                        {
                            ErrorSemantico(funcion, "La funcion no existe");
                            val = new NodoValor(null,-1);
                        }
                        else
                        {
                            val = new NodoValor(funcion, buscada.getTipo());
                        }

                    }
                }

            }
            
        }
        else
        {
            Sim buscada = buscarFuncion(funcion, nombreclase, numpar, params);
            if(buscada==null)
            {
                val = new NodoValor(null,-1);
                ErrorSemantico(funcion, "La funcion no existe");
            }
            else
            {
                    if(buscada.getTipo()==Tipo.PRIVATE || buscada.getTipo()==Tipo.PROTECTED)
                    {
                        ErrorSemantico(funcion, "La funcion no existe");
                        val = new NodoValor(null,-1);
                    }
                    else
                    {
                        val = new NodoValor(funcion, buscada.getTipo());
                    }
            }
        }

        return val;
    }

    public NodoValor verficarAccesoObjetos(Token objeto, Token atributo, String ambitoactual)
    {
        String nombreobj;
        String nombrefun;
        NodoValor val =null;

        Sim instancia = buscarVariable(objeto, ambitoactual);
        if(instancia!=null)
        {
            if(instancia.getRol().compareTo(Tipo.OBJETO)==0)
            {
                nombreobj = instancia.getInstancia();

                Sim buscada = buscarVariable(atributo, nombreobj);

                if(buscada==null)
                {
                    ErrorSemantico(atributo, "El atributo no existe");
                    val = new NodoValor(null,-1);
                }
                else
                {
                    if(buscada.getVisibilidad()==Tipo.PRIVATE || buscada.getVisibilidad()==Tipo.PROTECTED)
                    {
                        ErrorSemantico(atributo, "La funcion no existe");
                        val = new NodoValor(null,-1);
                    }
                    else
                    {
                        val = new NodoValor(atributo, buscada.getTipo());
                    }

                }
            }

        }




        return val;
    }

    public Sim buscarFuncion(Token fun,String clas ,int numpar, String params)
    {
        Sim encontrada = null;
        String rol;
        String nomfun = fun.getLexema();
        String name = clas+"#"+nomfun+params;
        for(Sim funcion: tabla)
        {
            rol = funcion.getRol();

            if(rol.compareTo(Tipo.FUNCION)==0)
            {

                if(funcion.getNombre().compareTo(nomfun)==0)
                {
                    if(numpar == funcion.getNumparams())
                    {
                        if(name.compareTo(funcion.getName())==0)
                        {
                            encontrada = funcion;
                            break;
                        }
                        
                    }
                }
                
                
            }
        }


        return encontrada;
    }

    public Sim BuscarClase(Token clas)
    {
        Sim buscada = null;
        boolean encontrada = false;
        String rol;
        String nom = clas.getLexema();
        for(Sim clase: tabla)
        {
            rol = clase.getRol();

            if(rol.compareTo(Tipo.CLASE)==0)
            {
                if(nom.compareTo(clase.getNombre())==0)
                {
                    encontrada = true;
                    buscada = clase;
                    break;
                }
            }
        }

        if(encontrada)
        {
            return buscada;
        }
        else
        {
            ErrorSemantico(clas,"La clase no existe");
            return null;
        }
    }

    public void agregarInstancia(int visibilidad,Token clase, Token var, Object valor, String ambitoactual, boolean global)
    {
        Sim simbolo;
        String nom;
        String name;
        Sim claseb = BuscarClase(clase);
        if(claseb!=null)
        {
            simbolo = new Sim();
            nom = var.getLexema();
            simbolo.setNombre(nom);
            simbolo.setVisibilidad(visibilidad);
            simbolo.setTipo(Tipo.INSTANCIA);
            simbolo.setRol(Tipo.OBJETO);
            simbolo.setAmbito(ambitoactual);
            name = ambitoactual+"#"+nom;
            simbolo.setName(name);
            simbolo.setInstancia(claseb.getNombre());
            simbolo.setSize(claseb.getSize());
            if(global)
            {
                simbolo.setPos(mem);
                simbolo.setPospila(-1);
                mem = mem + claseb.getSize();
            }
            else
            {
                simbolo.setPospila(pil);
                simbolo.setPos(-1);
                pil = pil + 1;
            }

            agregarVariableTabla(simbolo, var);

        }

    }

    public void verificarInstancias(Token clase, Token var, Object datos[])
    {
        String nomclaseins = clase.getLexema();
        Token tokenins;
        Sim clasebuscada = BuscarClase(clase);

        if(clasebuscada!=null)
        {
            if(datos!=null)
            {
                tokenins = (Token)datos[0];

                if(nomclaseins.compareTo(tokenins.getLexema())==0)
                {

                    
                    Sim buscada = buscarFuncion(tokenins, nomclaseins, (Integer)datos[1], datos[2].toString());
                    if(buscada==null)
                    {
                        ErrorSemantico(tokenins, "El constructor no existe");
                        
                    }
                    else
                    {
                        if(buscada.getVisibilidad()==Tipo.PRIVATE || buscada.getVisibilidad()==Tipo.PROTECTED)
                        {
                            ErrorSemantico(tokenins, "El constructor no existe");
                            
                        }
                        

                    }
                }
                else
                {
                    ErrorSemantico(tokenins, "No es una instancia de la clase "+nomclaseins);
                }
            }
        }

    }
    
    public Sim buscarFuncion(Token fun, String clas)
    {
        Sim encontrada = null;
        String rol;
        String nomfun = fun.getLexema();
        String name;
        for(Sim funcion: tabla)
        {
            rol = funcion.getRol();

            if(rol.compareTo(Tipo.FUNCION)==0)
            {

                if(funcion.getNombre().compareTo(nomfun)==0)
                {
                        name = funcion.getAmbito();
                        if(name.compareTo(clas)==0)
                        {
                            encontrada = funcion;
                            break;
                        }
                        
                    
                }
                
                
            }
        }


        return encontrada;
    }
    
    public int verificarSizeDimension(Object dimension, String ambitoactual)
    {
        int res = -1;
        int size;
        Token var;
        if(dimension!=null)
        {
            try{
            size = Integer.parseInt(dimension.toString());
            
            res = size;
            
            }catch(NumberFormatException ex)
            {
                var = (Token)dimension;
                Sim simbolo = buscarVariable(var, ambitoactual);
                
                if(simbolo!=null)
                {
                    if(simbolo.getValor()!=null)
                    {
                        res = Integer.parseInt(simbolo.getValor().toString());
                    }
                    else
                    {
                        ErrorSemantico(var,"La variable no esta Inicializada");
                    }
                }
            }
            
        }
        
        return res;
    }
    
    public void verificarElementosArreglo(int numdim, Object var, String ambitoactual)
    {
        Token array = (Token)var;
        Sim simbolo = buscarVariable(array, ambitoactual);
        
        if(simbolo!=null)
        {
            int size = simbolo.getSize();
            
            if(numdim!=size)
            {
                ErrorSemantico(array, "El numero de elementos asignados no es valido deben ser: "+size+" elementos");
            }
            
        }
        
    }
    
    public NodoValor verificarNumeroDimensiones(int numdim, Object var, String ambitoactual,int sizemat)
    {
        Token array = (Token)var;
        Sim simbolo = buscarVariable(array, ambitoactual);
        NodoValor  nodo = null;
        if(simbolo!=null)
        {
            int size = simbolo.getDimensiones();
            
            if(numdim!=size)
            {
                ErrorSemantico(array, "El numero de dimensiones  no es valido deben ser: "+size+" dimensiones");
                nodo = new NodoValor(null,-1);
            }
            else
            {
                if(sizemat != -1)
                {
                    if(sizemat < 0 || sizemat > simbolo.getSize())
                    {
                        ErrorSemantico(array, "El tamaño de las dimensiones no es valido");
                        nodo = new NodoValor(null,-1);
                    }
                    else
                    {
                        nodo = new NodoValor(array,simbolo.getTipo());
                    }
                }
                else
                {
                    nodo = new NodoValor(array,simbolo.getTipo());
                }
                
                
            }
            
        }
        
        return nodo;
        
    }
    
    public String tamDimension(Token arr,String ambitoactual, int dim)
    {
        int ind;
        String dimen="";
        Sim aux;
        ArrayList<String> dims;
        
        aux = buscarVariable(arr,ambitoactual);
        
        if(aux!=null)
        {
            dims = aux.getTam_dimensiones();
            
            if(dim<=dims.size())
            {
                ind = dim-1;
                dimen = dims.get(ind);
            }
        }
        
        return dimen;
    }
    
    public void agregarHerencia(Token var, Token hereda)
    {
        String nombre = var.getLexema();
        String nombrehereda = hereda.getLexema();
        Sim nuevo;
        String ambito;
        String clase;
        ArrayList<Sim> tablatemp = new ArrayList<Sim>();
        String name;
        for(Sim simbolo : tabla)
        {
            ambito = simbolo.getAmbito();
            name = simbolo.getName();
            if(ambito!=null)
            {
                clase = ambito.split("/")[0];
            
                if(nombre.compareTo(clase)==0)
                {
                    if(simbolo.getVisibilidad()!=Tipo.PRIVATE)
                    {
                        nuevo = new Sim();
                        nuevo.setAmbito(ambito.replace(ambito, nombrehereda));
                        nuevo.setDimensiones(simbolo.getDimensiones());
                        nuevo.setHeredade(simbolo.getHeredade());
                        nuevo.setInstancia(simbolo.getInstancia());
                        nuevo.setName(name.replace(ambito, nombrehereda));
                        nuevo.setNombre(simbolo.getNombre());
                        nuevo.setNumparams(simbolo.getNumparams());
                        nuevo.setParams(simbolo.getParams());

                        if(simbolo.getPospila()==-1)
                        {
                            nuevo.setPos(mem);
                            nuevo.setPospila(-1);
                            mem = mem + simbolo.getSize();
                        }
                        else
                        {
                            nuevo.setPos(-1);
                            nuevo.setPospila(pil);
                            pil = pil + simbolo.getSize();
                        }

                        nuevo.setReferencia(simbolo.getReferencia());
                        nuevo.setRol(simbolo.getRol());
                        nuevo.setSize(simbolo.getSize());
                        nuevo.setTam_dimensiones(simbolo.getTam_dimensiones());
                        nuevo.setTipo(simbolo.getTipo());
                        nuevo.setValor(simbolo.getValor());
                        nuevo.setVisibilidad(simbolo.getVisibilidad());
                        tablatemp.add(nuevo);
                    }
                }
            }
            
        }
        
        
        tabla.addAll(tablatemp);
        
        
    }
    
    
}
